<script>
import {
  defineComponent,
  nextTick,
  onMounted,
  onBeforeUnmount,
  reactive,
  ref,
  toRefs,
  watch
} from "vue";
import ComPreview from "../../components/ComPreview.vue";
import {dateFormat} from "@/utils/date.js";
import {
  ArrowLeft,
  ArrowRight,
  DArrowLeft,
  DArrowRight,
  Search,
  Download,
  Delete,
} from "@element-plus/icons-vue";
import {
  getListByDate,
  getFileList,
  fileDownloadByPath,
  deleteFileById,
} from "@/api/file.js";
import streamSaver from "streamsaver";
import {useUserStore} from "@/store/modules/user.js";
import {getConfigList, getTimeFiles} from "@/api/configure.js";

export default defineComponent({
  components: {
    ComPreview,
  },
  setup() {
    const defaultTime1 = new Date(2001, 1, 1, 0, 0, 0);
    const defaultTime2 = new Date(2001, 1, 1, 23, 59, 59);

    const state = reactive({
      rtspUrl: "",
      listHeight: 0,
      selectDay: new Date(),
      list: [],
      currentRow: null,
      videoUrl: "",
      flvPlayer: "",
      downLoadDialogVisible: false,
      queryForm: {
        fileType: 0,
        endTime: null,
        startTime: null,
      },
      fileList: [],
      selectFile: {},
      ipAddress: "",
      isActive: false,
      hasVideoDateList: [],
    });

    watch(() => state.selectDay, () => {
      searchList()
    })

    const icons = reactive({
      ArrowLeft,
      ArrowRight,
      DArrowLeft,
      DArrowRight,
      Search,
      Download,
      Delete,
    });

    const refComPreview = ref(null);
    const refCalendar = ref(null);
    const refOperationBound = ref(null);
    const refSearchButton = ref(null);
    const flvRef = ref(null);
    const fileTable = ref(null);

    const store = useUserStore();

    const getDayList = () => {
      let date = state.selectDay.toLocaleDateString().split("/");
      let date2 = date.map((item) => {
        if (item.length === 1) {
          return "0" + item;
        } else {
          return item;
        }
      });

      let str = date2.join("/");

      getListByDate(str).then((res) => {
        state.list = res.data;
      });
    };

    const calcListHeight = () => {
      nextTick(() => {
        const operationBoundHeight = refOperationBound.value.clientHeight;
        const calendarHeight = refCalendar.value.$el.clientHeight;
        let searchButtonHeight = 0
        if(refSearchButton.value) {
          searchButtonHeight = refSearchButton.value.$el.clientHeight;
        }

        state.listHeight =
            operationBoundHeight - calendarHeight - searchButtonHeight - 26;
      });
    };

    onMounted(() => {
      calcListHeight();
      getConfigList(0).then((res) => {
        state.ipAddress = res.data.configNetworkTCPIP.deviceIpv4Addr;
      });
      getTimeFiles().then((res) => {
        state.hasVideoDateList = res.data.data;
      });
    });

    onBeforeUnmount(() => {
      if (state.flvPlayer) {
        state.flvPlayer.destroy();
      }
    });

    const videoPlay = async () => {
      if (!state.currentRow) {
        return;
      }
      state.isActive = true;
      let str = state.currentRow.src;
      let strArr = str.split("/");
      let url1 = strArr[strArr.length - 2];
      let url2 = strArr[strArr.length - 1];
      state.videoUrl =
          "http://" + state.ipAddress + ":80/videos/" + url1 + "/" + url2;
      // state.videoUrl = "http://" + state.ipAddress + ":19999/videos/" + url2;
    };

    const handleSetDate = (e) => {
      if (refCalendar.value) {
        refCalendar.value.selectDate(e);
      }
    };

    const handleCurrentChange = (e) => {
      state.currentRow = e;
      videoPlay();
    };

    const searchList = () => {
      getDayList();
    };

    const handlePlay = () => {
      const videoElement = document.getElementById("videoElement");
      videoElement.play();
      // state.flvPlayer.play();
    };

    const handleStop = () => {
      const videoElement = document.getElementById("videoElement");
      videoElement.pause();
      // state.flvPlayer.stop();
    };

    const handleDown = () => {
      state.downLoadDialogVisible = true;
    };

    const handleFileSearch = () => {
      getFileList({
        fileType: state.queryForm.fileType,
        startTime: state.queryForm.startTime || "",
        endTime: state.queryForm.endTime || "",
        fileSuffix: 0,
      }).then((res) => {
        state.fileList = res.data;
      });
    };

    const selectItem = (any, val) => {
      fileTable.value.clearSelection();
      fileTable.value.toggleRowSelection(val);
      state.selectFile = val;
    };

    //文件下载
    const fileDownload = async () => {
      if (!state.selectFile.src) {
        return;
      }
      let fullPath = state.selectFile.src;

      await fetch(`api/file/download?fullPath=${fullPath}`, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${store.token}`,
        },
      }).then((res) => {
        fileTable.value.clearSelection();
        let name = state.selectFile.fileName;
        state.selectFile = {};
        const fileStream = streamSaver.createWriteStream(name, {
          size: res.headers.get("content-length"),
        });
        const readableStream = res.body;

        if (window.WritableStream && readableStream.pipeTo) {
          return readableStream.pipeTo(fileStream).then(() => {
          });
        }

        window.writer = fileStream.getWriter();
        const reader = res.body.getReader();
        const pump = () =>
            reader
                .read()
                .then((res) =>
                    res.done
                        ? window.writer.close()
                        : window.writer.write(res.value).then(pump)
                );
        pump();
      });
    };

    //删除文件
    const deleteFile = () => {
      if (state.selectFile.id.length <= 0) {
        return;
      }
      let id = state.selectFile.id;
      deleteFileById(id).then(
          (res) => {
            ElMessage({
              message: "删除成功",
              type: "success",
              offset: 400,
            });
            handleFileSearch();
          },
          (err) => {
            ElMessage({
              message: "删除失败",
              type: "warning",
              offset: 400,
            });
          }
      );
    };

    return {
      ...toRefs(state),
      ...toRefs(icons),
      refComPreview,
      refCalendar,
      refOperationBound,
      refSearchButton,
      handleSetDate,
      handleCurrentChange,
      searchList,
      handlePlay,
      handleStop,
      handleDown,
      handleFileSearch,
      dateFormat,
      selectItem,
      fileTable,
      flvRef,
      fileDownload,
      deleteFile,
      defaultTime1,
      defaultTime2,
    };
  },
});
</script>

<template>
  <div class="playback-container">
    <div class="flv-bound">
      <div class="shade" :class="{ active: isActive }">
        <div class="textTitle">暂无视频</div>
      </div>
      <video
          class="video-meaner"
          :src="videoUrl"
          id="videoElement"
          controls
          autoplay
      >
        <!-- <source :src="videoUrl" type="video/mp4" /> -->
      </video>
      <div class="controls">
        <span ref="flvRef" @click="handlePlay">播放</span>
        <span @click="handleStop">暂停</span>
        <span @click="handleDown">下载</span>
      </div>
    </div>
    <div ref="refOperationBound" class="operation-bound">
      <el-calendar ref="refCalendar" v-model="selectDay">
        <template #header="{ date }">
          <div class="calendar-header">
            <el-button
                :icon="DArrowLeft"
                link
                @click="handleSetDate('prev-year')"
            />
            <el-button
                :icon="ArrowLeft"
                link
                @click="handleSetDate('prev-month')"
            />
            <span>{{ date }}</span>
            <el-button
                :icon="ArrowRight"
                link
                @click="handleSetDate('next-month')"
            />
            <el-button
                :icon="DArrowRight"
                link
                @click="handleSetDate('next-year')"
            />
          </div>
        </template>
        <template #date-cell="{ data }">
          <el-badge v-if="hasVideoDateList.includes(data['day'])" is-dot>
            <span>{{ data["day"].split("-")[2] }}</span>
          </el-badge>
        </template>
      </el-calendar>
      <el-button
          v-if="false"
          ref="refSearchButton"
          :icon="Search"
          type="primary"
          style="margin-top: 12px; width: 100%; background-color: #fe6266"
          @click="searchList"
      >查找
      </el-button
      >
      <div class="list-bound" :style="{ height: listHeight + 'px' }">
        <el-table
            :max-height="listHeight"
            :data="list"
            highlight-current-row
            :cell-style="{ cursor: 'pointer', userSelect: 'none' }"
            @current-change="handleCurrentChange"
        >
          <el-table-column label="#" type="index" :width="65"/>
          <el-table-column
              label="文件名"
              prop="fileName"
              show-overflow-tooltip
          />
        </el-table>
      </div>
    </div>

    <el-dialog title="下载" v-model="downLoadDialogVisible" :width="960">
      <div class="dialog-download-container">
        <div class="download-filter-box">
          <div class="filter-header">查询条件</div>
          <div class="form-bound">
            <el-form label-position="top">
              <el-form-item label="文件类型">
                <el-select v-model="queryForm.fileType">
                  <el-option label="录制文件" :value="0"/>
                  <el-option label="定时文件" :value="1"/>
                </el-select>
              </el-form-item>
              <el-form-item label="开始时间">
                <el-date-picker
                    type="datetime"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    style="width: 100%"
                    v-model="queryForm.startTime"
                    :default-time="defaultTime1"
                    placeholder="请选择时间"
                />
              </el-form-item>
              <el-form-item label="结束时间">
                <el-date-picker
                    type="datetime"
                    format="YYYY/MM/DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    :default-time="defaultTime2"
                    style="width: 100%"
                    v-model="queryForm.endTime"
                />
              </el-form-item>
            </el-form>
            <el-button
                :icon="Search"
                type="primary"
                style="width: 100%; background-color: #fe6266"
                @click="handleFileSearch"
            >查找
            </el-button
            >
          </div>
        </div>
        <div class="download-file-box">
          <div class="file-header">
            <span>文件列表</span>
            <div class="button-group">
              <el-button :icon="Download" size="small" @click="fileDownload"
              >下载
              </el-button
              >
              <el-button :icon="Delete" size="small" @click="deleteFile"
              >删除
              </el-button
              >
            </div>
          </div>
          <div class="file-bound">
            <el-table
                ref="fileTable"
                :max-height="536"
                :data="fileList"
                @select="selectItem"
            >
              <el-table-column type="selection"/>
              <el-table-column
                  show-overflow-tooltip
                  label="序号"
                  type="index"
                  :width="85"
              />
              <el-table-column
                  show-overflow-tooltip
                  label="文件名"
                  prop="fileName"
              />
              <el-table-column show-overflow-tooltip label="开始时间">
                <template #default="scope">
                  <span>{{
                      dateFormat("yyyy-MM-dd hh:mm:ss", scope.row["startTime"])
                    }}</span>
                </template>
              </el-table-column>
              <el-table-column show-overflow-tooltip label="结束时间">
                <template #default="scope">
                  <span>{{
                      dateFormat("yyyy-MM-dd hh:mm:ss", scope.row["endTime"])
                    }}</span>
                </template>
              </el-table-column>
              <el-table-column
                  show-overflow-tooltip
                  label="文件大小"
                  prop="fileSize"
              />
              <el-table-column show-overflow-tooltip label="下载进度"/>
            </el-table>
          </div>
          <div class="file-footer"></div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<style lang="scss">
.playback-container {
  height: 100%;
  display: flex;
  justify-content: space-between;
  padding-top: 12px;

  .flv-bound {
    width: calc(100% - 315px);
    height: 100%;

    .shade {
      width: calc(100% - 315px);
      height: calc(100% - 36px);
      position: fixed;
      z-index: 1000;
      background-color: rgb(136, 147, 148);
      color: white;
      font-size: 36px;
      text-align: center;

      .textTitle {
        position: relative;
        top: 40%;
      }
    }

    .active {
      display: none;
    }
  }

  .controls {
    height: 32px;
    background-color: #f2f2f2;
    color: #101010;
    padding: 0 20px;
    display: flex;
    align-items: center;
    justify-content: flex-end;

    span {
      margin-left: 8px;
      font-size: 12px;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      cursor: pointer;
    }
  }

  .video-meaner {
    width: 100%;
    height: calc(100% - 36px);
    // 如果不生效，加！important;
    /* 全屏按钮 */
    &::-webkit-media-controls-fullscreen-button {
      display: none;
    }

    /* 播放按钮 */
    &::-webkit-media-controls-play-button {
      display: none;
    }

    /* 进度条 */
    &::-webkit-media-controls-timeline {
      display: none;
    }

    /* 观看的当前时间 */
    &::-webkit-media-controls-current-time-display {
      display: none;
    }

    /* 剩余时间 */
    &::-webkit-media-controls-time-remaining-display {
      display: none;
    }

    /* 音量按钮 */
    &::-webkit-media-controls-mute-button {
      display: none;
    }

    /* 音量控制条 */
    &::-webkit-media-controls-volume-slider {
      display: none;
    }

    /* 所有控件 */
    &::-webkit-media-controls-enclosure {
      display: none;
    }
  }

  .operation-bound {
    width: 300px;
    height: 100%;
    padding-right: 12px;

    .list-bound {
      margin-top: 12px;
    }

    .el-calendar__header {
      padding: 0;

      .calendar-header {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-between;
      }
    }

    .el-calendar__body {
      padding: 0;

      .el-calendar-table {
        thead {
          th {
            background-color: #1890ff;
            color: #fcfdff;
          }
        }

        tbody {
          .el-calendar-table__row {
            .prev,
            .current,
            .next {
              .el-calendar-day {
                padding: 0;
                height: 39px;
                display: flex;
                align-items: center;
                justify-content: center;
              }
            }
          }
        }
      }
    }
  }

  .el-dialog {
    padding: 8px;

    .el-dialog__header.show-close {
      padding-bottom: 4px;
    }

    .dialog-download-container {
      height: 600px;
      display: flex;

      .download-filter-box {
        width: 300px;
        height: 100%;

        .filter-header {
          height: 32px;
          background-color: #e6e6e6;
          color: #696969;
          font-weight: 600;
          padding-left: 8px;
          display: flex;
          align-items: center;
          justify-content: space-between;
        }

        .form-bound {
          padding: 12px;
        }
      }

      .download-file-box {
        width: calc(100% - 300px);
        height: 100%;
        border: 1px solid #afafaf;

        .file-header {
          height: 32px;
          background-color: #e6e6e6;
          color: #696969;
          font-weight: 600;
          padding: 0 8px;
          display: flex;
          align-items: center;
          justify-content: space-between;

          .button-group {
            display: flex;
            align-items: center;
            justify-content: center;
          }
        }

        .file-bound {
          height: 536px;
        }

        .file-footer {
          height: 32px;
          background-color: #e6e6e6;
        }

        th {
          .cell {
            .el-checkbox {
              .el-checkbox__input {
                display: none;
              }
            }
          }
        }
      }
    }
  }
}
</style>
